package com.burgeon.backend.SHOP.service.Impl;

import com.alibaba.fastjson.JSONArray;
import com.burgeon.backend.Rest.User.CreateUser;
import com.burgeon.backend.SHOP.entity.PickingCard;
import com.burgeon.backend.SHOP.entity.PickingCardItem;
import com.burgeon.backend.SHOP.entity.Wechat;
import com.burgeon.backend.SHOP.mappers.AppCouponMapper;
import com.burgeon.backend.SHOP.mappers.AppUserMapper;
import com.burgeon.backend.SHOP.mappers.PlusActiveMapper;
import com.burgeon.backend.SHOP.mappers.WechatAppMapper;
import com.burgeon.backend.SHOP.rest.*;
import com.burgeon.backend.SHOP.service.AppUserService;
import com.burgeon.backend.SHOP.service.ex.ErrorDataExceptionApp;
import com.burgeon.backend.SHOP.service.ex.LoggingExceptionApp;
import com.burgeon.backend.SHOP.service.ex.PhoneExceptionApp;
import com.burgeon.backend.SHOPBACKEND.entity.Employee;
import com.burgeon.backend.SHOPBACKEND.rest.ModVipLogo;
import com.burgeon.backend.SHOPBACKEND.service.BackendCouponGiftService;
import com.burgeon.backend.SHOPBACKEND.service.ex.DataNotFoundException;
import com.burgeon.backend.entity.*;
import com.burgeon.backend.mappers.AccountMapper;
import com.burgeon.backend.mappers.FieldsMapper;
import com.burgeon.backend.mappers.StoreMapper;
import com.burgeon.backend.mappers.TemplateMapper;
import com.burgeon.backend.service.QueueService;
import com.burgeon.backend.service.WechatService;
import com.burgeon.backend.service.ex.InsertException;
import com.burgeon.backend.service.ex.UserNotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;


@Service
public class AppUserServiceImpl implements AppUserService {

    private final static Log logger = LogFactory.getLog(AppUserService.class);

    @Autowired
    private WechatAppMapper wechatAppMapper;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private AppUserMapper appUserMapper;
    @Autowired
    private FieldsMapper fieldsMapper;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private AppCouponMapper appCouponMapper;
    @Autowired
    private TemplateMapper templateMapper;
    @Autowired
    private QueueService queueService;
    @Autowired
    private WechatService wechatService;
    @Autowired
    private BackendCouponGiftService backendCouponGiftService;
    @Autowired
    private PlusActiveMapper plusActiveMapper;



    @Override
    public List<Employee> GetEmpDataBylog(String id, String token) {
        Info info = GetInfoByToken(token);
        FindEmpDataByStoreId findEmpDataByStoreId = new FindEmpDataByStoreId(info.getUrl(), info.getAccount(), info.getPassword());

        try {
            ArrayList<Employee> data = findEmpDataByStoreId.getData(id);
            for (Employee employee : data) {
                employee.setImg(appUserMapper.findData(employee.getId(), token));
            }
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    @Transactional
    public HashMap AppUserLoginByModEmp(User user, HttpSession session) throws LoggingExceptionApp {
        System.err.println("user=" + user);
        Info info = GetInfoByToken(user.getToken());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateString = sdf.format(new Date());
        user.setAccount(user.getToken());
        user.setCreateTime(dateString);
        user.setFinish("Y");
        user.setType(fieldsMapper.GetDataToken(user.getToken()).getType());


        FindDiscountByVipType findDiscountByVipType = new FindDiscountByVipType(info.getUrl(), info.getAccount(), info.getPassword());
        String discount = null;
        try {
            discount = findDiscountByVipType.getData(user.getType());
        } catch (Exception e) {
            e.printStackTrace();
        }
        session.setAttribute("user_discount", discount);//缓存会员折扣
        session.setAttribute("user_is_plus", "N");
        user.setIsPlus("N");
        user.setDiscount(discount);

        CreateUser createUser = new CreateUser(info.getUrl(), info.getAccount(), info.getPassword());
        FindStoreByEmp findStoreByEmp = new FindStoreByEmp(info.getUrl(), info.getAccount(), info.getPassword());
        try {
            HashMap<String, String> empData = findStoreByEmp.getData(user.getEmp());
            user.setEmp(empData.get("NO"));
            user.setStore(empData.get("store"));
            user.setStorejh(user.getStore());
            user.setCustomer(empData.get("customerup"));
            user.setSource("Z");//来源注册
            Integer row = appUserMapper.AddUser(user);

            if (row != 1) {
                throw new InsertException("注册数据异常");
            }


            //写入erp
            System.err.println("user=" + user);
            createUser.getData(user);
            session.setAttribute("uid", user.getId());
            //查询折扣
            TemplateSwitch templateSwitch = templateMapper.FindTemplateSwitch(user.getAccount());

            System.err.println("templateSwitch========================"+templateSwitch);
            if ("Y".equals(templateSwitch.getSwitch2())) {
                logger.info("新用户送券"+user.getName()+user.getPhone());
                if ("D".equals(templateSwitch.getFlag()) && templateSwitch.getFlag() != "" && templateSwitch.getFlag() != null){
                    //新用户送单券
                    queueService.putNewUserCoupon(templateSwitch.getValue2(), user.getPhone(), user.getToken());
                }
                if ("T".equals(templateSwitch.getFlag()) && templateSwitch.getFlag() != "" && templateSwitch.getFlag() != null){
                    //新用户送套券
                    backendCouponGiftService.createCoupon(templateSwitch.getValue2(),user.getPhone(),user.getToken());
                }

            }
            if ("Y".equals(templateSwitch.getSwitch1())) {
                logger.info("新用户送积分"+user.getName()+user.getPhone());
                System.err.println("积分=========================="+templateSwitch.getValue1());
                queueService.putNewUserIntegral(user.getName(), user.getPhone(), user.getOpenid(), templateSwitch.getValue1(), user.getToken());
            }

            return empData;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("注册出错" + e.getMessage());
            throw new InsertException("注册出错，稍后重试");
        }


    }

    @Override
    public HashMap modEmpData(String phone, String id, String token) throws ErrorDataExceptionApp {
        System.err.println("id============================="+id);
        Info info = GetInfo(token);
        //查导购所属店仓
        FindStoreByEmp findStoreByEmp = new FindStoreByEmp(info.getUrl(), info.getAccount(), info.getPassword());
        ModVipEmp modVipEmp = new ModVipEmp(info.getUrl(), info.getAccount(), info.getPassword());
        GETUserByPhone getUserByPhone = new GETUserByPhone(info.getUrl(), info.getAccount(), info.getPassword());
        ModVipLogo modVipLogo = new ModVipLogo(info.getUrl(), info.getAccount(), info.getPassword());
        try {
            User user = getUserByPhone.getData(phone);
            HashMap<String, String> erpData = findStoreByEmp.getData(id);

            //导购头像
            System.err.println("参数========================"+id+token);
            String img = appUserMapper.findData(id, token);
            System.err.println("导购头像======"+img);
            if(null == img){
                erpData.put("img", "");
            }else {
                erpData.put("img", img);
            }

            if ("Y".equals(user.getStorejh())){
                user.setStorejh(erpData.get("store"));
            }
            modVipEmp.getData(user.getId(), erpData.get("NO"),user.getStorejh());
            erpData.put("isEmp", user.getIsEmp());
            if ("null".equals(user.getLogoUrl())) {
                String uImg = appUserMapper.GetUserImgByPhone(phone, token);
                modVipLogo.getData(user.getId(), uImg);
            }
            return erpData;
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("绑定错误");
            throw new ErrorDataExceptionApp(e.getMessage());
        }


    }

    @Override
    public List<PickingCard> getPickingCard(String phone, String token) {
        Info info = GetInfo(token);
        FindPICKINGCARD findPICKINGCARD = new FindPICKINGCARD(info.getUrl(), info.getAccount(), info.getPassword());
        try {
            return findPICKINGCARD.getData(phone);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<PickingCardItem> getPickingCardItem(String id, String token) {
        Info info = GetInfo(token);
        FindPICKINGCARDITEM findPICKINGCARDITEM = new FindPICKINGCARDITEM(info.getUrl(), info.getAccount(), info.getPassword());
        try {
            return findPICKINGCARDITEM.getData(id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Store> GetStores(String city, String token) {
        Info info = GetInfo(token);
        GetStoreByCityForLog getStoreByCityForLog = new GetStoreByCityForLog(info.getUrl(), info.getAccount(), info.getPassword());
        try {
            return getStoreByCityForLog.getData(city);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    @Transactional
    public void AppUserLogin(User user, HttpSession session) throws LoggingExceptionApp {
        System.err.println("user=" + user);
        logger.error(user);
        Info info = GetInfoByToken(user.getToken());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateString = sdf.format(new Date());
        user.setAccount(user.getToken());
        user.setCreateTime(dateString);
        user.setFinish("Y");
        user.setType(fieldsMapper.GetDataToken(user.getToken()).getType());
        FindDiscountByVipType findDiscountByVipType = new FindDiscountByVipType(info.getUrl(), info.getAccount(), info.getPassword());
        String discount = null;
        try {
            discount = findDiscountByVipType.getData(user.getType());
        } catch (Exception e) {
            e.printStackTrace();
        }
        user.setDiscount(discount);
        user.setIsPlus("N");
        user.setSource("Z");//来源注册
        user.setStorejh(user.getStore());
        Integer row = appUserMapper.AddUser(user);
        session.setAttribute("user_discount", discount);//缓存会员折扣
        session.setAttribute("user_is_plus", "N");
        if (row != 1) {
            throw new InsertException("注册数据异常");
        }

        CreateUser createUser = new CreateUser(info.getUrl(), info.getAccount(), info.getPassword());
        FindStoreByEmp findStoreByEmp = new FindStoreByEmp(info.getUrl(), info.getAccount(), info.getPassword());


        try {
            HashMap<String, String> erpData = findStoreByEmp.getData(user.getEmp());
            //写入erp
            user.setCustomer(erpData.get("customerup"));
            user.setEmp(erpData.get("NO"));
            System.err.println("user=" + user);

            createUser.getData(user);

            //查询折扣

            session.setAttribute("uid", user.getId());
            session.setAttribute("user_discount", discount);//缓存会员折扣
            session.setAttribute("user_is_plus", "N");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("注册出错" + e.getMessage());
            throw new InsertException("注册出错，稍后重试");
        }

        TemplateSwitch templateSwitch = templateMapper.FindTemplateSwitch(user.getAccount());

        if ("Y".equals(templateSwitch.getSwitch2())) {
            if("D".equals(templateSwitch.getFlag())){
                //新用户送券单券
                queueService.putNewUserCoupon(templateSwitch.getValue2(), user.getPhone(), user.getToken());
            }
            if ("T".equals(templateSwitch.getFlag())){
                //新用户送套券
                backendCouponGiftService.createCoupon(templateSwitch.getValue2(),user.getPhone(),user.getToken());
            }
        }
        if ("Y".equals(templateSwitch.getSwitch1())) {

            queueService.putNewUserIntegral(user.getName(), user.getPhone(), user.getOpenid(), templateSwitch.getValue1(), user.getToken());
        }

    }


    /**
     * 解密手机号 判断手机号是否存在
     * 存在写入小程序openid
     * 不存在返回跳转注册
     *
     * @param mag
     * @param iv
     * @param sessionkey
     * @return
     */
    @Override
    public User GetPhone(String mag, String iv, String sessionkey, String token, String openid,
                         String openid_v, String img,String nickName, HttpSession session) throws PhoneExceptionApp {
        String resultMessage = null;
        User user = new User();
        String phone;
        try {
            resultMessage = decryptS5(mag, "UTF-8", sessionkey, iv);
            System.err.println(resultMessage);
            JSONObject jsonObject = new JSONObject(resultMessage);
            phone = jsonObject.getString("purePhoneNumber");

            Fields fields = fieldsMapper.GetDataToken(token);
            //多品牌加前缀
            if ("Y".equals(fields.getPrefix())) {
                phone = fields.getPrefixValue() + phone;
            }
            user = appUserMapper.GetUserByPhone(phone, token);
            Info info = GetInfo(token);

            GETUserByPhone getUserByPhone = new GETUserByPhone(info.getUrl(), info.getAccount(), info.getPassword());
            User erpUser = new User();
            UserReadAppOpenid userReadAppOpenid = new UserReadAppOpenid(info.getUrl(), info.getAccount(), info.getPassword());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String dateString = sdf.format(new Date());
            try {
                erpUser = getUserByPhone.getData(phone);//无数据抛异常
                session.setAttribute("user_discount", erpUser.getDiscount());//缓存会员折扣
                session.setAttribute("user_is_plus", erpUser.getIsPlus());
                erpUser.setAppOpenid(openid);
                erpUser.setOpenid(openid_v);
                erpUser.setToken(token);
                erpUser.setAccount(token);
                erpUser.setFinish("Y");
                erpUser.setCreateTime(dateString);
                System.err.println("user=" + erpUser);
                String erpUid = erpUser.getId();
                if (null == user) {
                    erpUser.setImg(img);
                    erpUser.setSource("B");//来源绑定
                    if ("N".equals(erpUser.getStorejh())){
                        erpUser.setStorejh(null);
                    }
                    appUserMapper.AddUser(erpUser);
                    TemplateSwitch templateSwitch = templateMapper.FindTemplateSwitch(token);

                    if ("Y".equals(templateSwitch.getSwitch2())) {
                        //新用户送券
                        queueService.putNewUserCoupon(templateSwitch.getValue2(),phone, token);
                    }
                    if ("Y".equals(templateSwitch.getSwitch1())) {

                        queueService.putNewUserIntegral(erpUser.getName(), phone, openid_v, templateSwitch.getValue1(), token);
                    }
                    user = new User();
                    user.setId(erpUser.getId());
                } else {
                    appUserMapper.UpAppOpenidByPhone(phone, openid, openid_v,
                            erpUser.getDiscount(), erpUser.getIsPlus(), token);
                }

                userReadAppOpenid.getData(erpUid, openid, openid_v,nickName);//修改openid
                user.setExist("Y");
            } catch (UserNotFoundException e) {
                user = new User();
                user.setExist("N");//user不存在
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new PhoneExceptionApp("获取失败");
        }

        user.setPhone(phone);
        return user;
    }

    @Override
    public User Log(String code, String token, HttpSession session) throws LoggingExceptionApp {
        Wechat data = getInfo(token);

        String url = "https://api.weixin.qq.com/sns/jscode2session?" +
                "appid=" + data.getAppid() +
                "&secret=" + data.getAppsecret() +
                "&js_code=" + code +
                "&grant_type=authorization_code";

        RestTemplate restTemplate = new RestTemplate();
        String str = restTemplate.getForObject(url, String.class);
        System.err.println("wechatcode" + str);
        //  Info info = GetInfo(token);
        //  GETUserByOpenid getUserByOpenid = new GETUserByOpenid(info.getUrl(), info.getAccount(), info.getPassword());
        try {
            JSONObject jsonObject = new JSONObject(str);
            String session_key = jsonObject.getString("session_key");
            String openid = jsonObject.getString("openid");
//            String unionid = jsonObject.getString("unionid");
            session.setAttribute("session_key", session_key);
            session.setAttribute("app_openid", openid);
            User user = appUserMapper.GetUserByOpenid(openid, token);
            //是否员工 无 N  有 显示名称
            if (null != user && null == user.getIsEmp()) {
                user.setIsEmp("N");
            }
            if (null != user && null != user.getDiscount()) {
                session.setAttribute("user_discount", user.getDiscount());//缓存会员折扣
            }

            if (null != user && null != user.getIsPlus() && "Y".equals(user.getIsPlus())) {
                session.setAttribute("user_is_plus", "Y");
            }
            if (null != user && null != user.getId()) {
                session.setAttribute("uid", user.getId());
            }
            if (null != user && null != user.getPhone()) {
                session.setAttribute("phone", user.getPhone());
            }
            if (null != user && null == user.getIsOfficial()) {
//                if(jsonObject.has("unionid")){
//                    appUserMapper.UpIsOfficial("Y",openid,token);
//                }else {
//                    appUserMapper.UpIsOfficial("N",openid,token);
//                }
                String accessToken = wechatService.GetAccesToken(token);
                com.alibaba.fastjson.JSONObject json = getUserInfo(accessToken,user.getOpenid(),token);
                System.err.println(json);
                if (null != json) {
                    if (!json.containsKey("errcode")) {
                        String subscribe = json.getString("subscribe");
                        if ("0".equals(subscribe)) {
                            appUserMapper.UpIsOfficial("N", user.getId(), token);
                            logger.info("用户并没有关注本公众号subscribe=" + subscribe);
                        } else if ("1".equals(subscribe)) {
                            appUserMapper.UpIsOfficial("Y", user.getId(), token);
                        }
                    }
                }

            }

            return user;

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("登录错误" + e.getMessage());
        }
        return null;
    }

    @Override
    public User GetUserData(String openid, String token) {

        Info info = GetInfo(token);
        GETUserByOpenid getUserByOpenid = new GETUserByOpenid(info.getUrl(), info.getAccount(), info.getPassword());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        try {
            User user = getUserByOpenid.getData(openid);

            int dueRemind = Integer.parseInt(plusActiveMapper.findDueRemind(token));

            String expiryDays = plusActiveMapper.findExpiryDays(token, openid);

            if(expiryDays == null || Integer.parseInt(expiryDays) <= 0) {
                user.setExpiryDays("N");//未开通过Plus或者已过期
            }else if (expiryDays != null && Integer.parseInt(expiryDays) > dueRemind){
                user.setExpiryDays("T");//未到过期提醒时间
            }else {
                user.setExpiryDays(expiryDays);
            }

            user.setCouQty(appCouponMapper.userCouponCount(user.getPhone(), sdf.format(new Date()), token));
            return user;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("GetUserData" + e.getMessage());
        }
        return null;

    }

    /**
     * 获取微信信息
     *
     * @param token
     * @return
     */
    private Wechat getInfo(String token) {
        return wechatAppMapper.getWechat(token);
    }

    private Info GetInfo(String token) {
        return accountMapper.GetTokenData(token);
    }

    private static String decryptS5(String sSrc, String encodingFormat, String sKey, String ivParameter) throws Exception {

      /*  try {
            Base64 base64 = new Base64();
            byte[] raw = (byte[]) base64.encode(sKey);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            IvParameterSpec iv = new IvParameterSpec(base64.decode(ivParameter));
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE,skeySpec,iv);
            byte[] myendicod = base64.decode(sSrc);
            byte[] original = cipher.doFinal(myendicod);
            String originalString = new String(original, encodingFormat);
            return originalString;

        }catch (Exception e){
            return null;
        }*/

        try {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] raw = decoder.decodeBuffer(sKey);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            IvParameterSpec iv = new IvParameterSpec(decoder.decodeBuffer(ivParameter));
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] myendicod = decoder.decodeBuffer(sSrc);
            byte[] original = cipher.doFinal(myendicod);
            String originalString = new String(original, encodingFormat);
            return originalString;
        } catch (Exception ex) {
            return null;
        }

    }

    public static void main(String[] args) throws Exception {
        System.out.println(decryptS5("1","2","3","4"));
    }

    private Info GetInfoByToken(String token) {
        return accountMapper.GetTokenData(token);
    }

    /**
     * 获取微信用户的信息
     * @param accessToken
     * @param openId
     * @return
     */
//    @Override
    private com.alibaba.fastjson.JSONObject getUserInfo(String accessToken, String openId, String token) throws DataNotFoundException {

        // 上传文件请求路径
        String action = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="
                + accessToken+"&openid="+openId;
        System.err.println("j呼吸道咖啡机"+openId);
        // 拼接获取用户信息接口的请求地址
//        String requestUrl = ProjectConst.GET_WEIXIN_USER_URL.replace("ACCESS_TOKEN", accessToken).replace(
//                "OPENID", openId);
        // 获取用户信息(返回的是Json格式内容)
        //封装获取到的用户信息

        try {
            URL urlGet = new URL(action);
            HttpsURLConnection http = (HttpsURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String result = new String(jsonBytes, "UTF-8");
            System.err.println("结果"+result);
            com.alibaba.fastjson.JSONObject jsonObject = JSONArray.parseObject(result);

            return jsonObject;
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("失败");
            return null;

        }

    }

}
